﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MyBet.Web;
using System.Windows.Data;
using MyBet.Helpers;
using MyBet.Class;
using System.Windows.Media.Imaging;
using System.Collections.Generic;

namespace MyBet
{
    public partial class Ranking : UserControl
    {
        private const int MaximumNumberOfUsers = 20;
        private EventRankGUI _currentEvent;
        private int _lastCustomContestLoaded = -1;

        public EventRankGUI CurrentEvent
        {
            get { return _currentEvent; }
            set { _currentEvent = value; }
        }

        System.Windows.Data.PagedCollectionView _paged;

        public System.Windows.Data.PagedCollectionView Paged
        {
            get { return _paged; }
            set { _paged = value; }
        }

        public Ranking()
        {
            // Required to initialize variables
            InitializeComponent();
            rankDataGrid.Visibility = Visibility.Collapsed;
            rankDataGridPager.Visibility = Visibility.Collapsed;
            RankDaysList.SelectionChanged += new SelectionChangedEventHandler(RankDaysList_SelectionChanged);
        }

        /// <summary>
        /// Load list of score
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            if ((App.CurrentUser != null) && (_lastCustomContestLoaded!=App.CurrentUser.CustomContestId))
            {
                // Get global rank
                //GetRanksSvc.GetRanksClient rankSvc = new GetRanksSvc.GetRanksClient();
                //rankSvc.GetContestRanksCompleted+=new EventHandler<GetRanksSvc.GetContestRanksCompletedEventArgs>(rankSvc_GetContestRanksCompleted);
                //rankSvc.GetContestRanksAsync(App.CurrentUser.CurrentContestId);
                // Get days list
                rankDataGrid.ClearValue(DataGrid.ItemsSourceProperty);
                BusyControl.IsBusy = true;
                BusyControl.BusyContent = Helpers.LangHelper.GetString("WaitingLoad");
                GetRanksSvc.GetRanksClient rankSvc2 = new GetRanksSvc.GetRanksClient();
                rankSvc2.GetEventsWithRankFromCustomContestCompleted += new EventHandler<GetRanksSvc.GetEventsWithRankFromCustomContestCompletedEventArgs>(rankSvc2_GetEventListCompleted);
                rankSvc2.GetEventsWithRankFromCustomContestAsync(App.CurrentUser.CustomContestId);
            }
        }

        /// <summary>
        /// Populate listbox with all days
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void rankSvc2_GetEventListCompleted(object sender, GetRanksSvc.GetEventsWithRankFromCustomContestCompletedEventArgs e)
        {
            if (null != e.Result)
            {

                RankDaysList.Items.Clear();
                RankDaysList.Items.Add(new EventRankGUI(EventRankGUI.RankType.General));
                RankDaysList.Items.Add(new EventRankGUI(EventRankGUI.RankType.Average));
                RankDaysList.SelectedIndex = 0;
                foreach (GetRanksSvc.EventObject evt in e.Result)
                {
                    EventRankGUI evtGUI = new EventRankGUI(evt);
                    RankDaysList.Items.Add(evtGUI);
                }
            }
        }

        /// <summary>
        ///  Callback when selection change
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void RankDaysList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if ((RankDaysList.SelectedValue != null) && (App.CurrentUser != null))
            {
                rankDataGrid.ClearValue(DataGrid.ItemsSourceProperty);
                if (LoadRank())
                {
                    BusyControl.IsBusy = false;
                }
                else
                {
                    BusyControl.IsBusy = true;
                    BusyControl.BusyContent = Helpers.LangHelper.GetString("WaitingLoad");   
                }
               
            }

        }

        /// <summary>
        /// Chargement du classement
        /// </summary>
        private bool LoadRank()
        {
            EventRankGUI evtGUI = RankDaysList.SelectedValue as EventRankGUI;
            CurrentEvent = evtGUI;
            // Get event rank
            GetRanksSvc.GetRanksClient rankSvc = new GetRanksSvc.GetRanksClient();
            rankSvc.GetCustomContestRanksFromEventCompleted += new EventHandler<GetRanksSvc.GetCustomContestRanksFromEventCompletedEventArgs>(rankSvc_GetContestRanksFromEventCompleted);

            if (evtGUI.Type == EventRankGUI.RankType.SpecificDay)
            {
                // event rank
                CurrentEvent.CurrentEventId = evtGUI.GetEvent._eventId;

                Dictionary<int, RankCache> currentCustomContestCache;
                if (!App.RankCacheDictionary.ContainsKey(App.CurrentUser.CustomContestId))
                {
                    App.RankCacheDictionary.Add(App.CurrentUser.CustomContestId, new Dictionary<int, RankCache>());
                }
                currentCustomContestCache = App.RankCacheDictionary[App.CurrentUser.CustomContestId];


                if (currentCustomContestCache.ContainsKey(CurrentEvent.CurrentEventId))
                {
                    RankCache currentCache = currentCustomContestCache[CurrentEvent.CurrentEventId];
                    if (!currentCache.IsDirty())
                    {
                        BindDataGrid(currentCache.Cache);
                        return true;
                    }
                }
                rankSvc.GetCustomContestRanksFromEventAsync(App.CurrentUser.CustomContestId, evtGUI.GetEvent._eventId);
            }
            else if (evtGUI.Type == EventRankGUI.RankType.Average)
            {
                // Average
                CurrentEvent.CurrentEventId = -1;

                Dictionary<int, RankCache> currentCustomContestCache;
                if (!App.RankCacheDictionary.ContainsKey(App.CurrentUser.CustomContestId))
                {
                    App.RankCacheDictionary.Add(App.CurrentUser.CustomContestId, new Dictionary<int, RankCache>());
                }
                currentCustomContestCache = App.RankCacheDictionary[App.CurrentUser.CustomContestId];

                if (currentCustomContestCache.ContainsKey(CurrentEvent.CurrentEventId))
                {
                    RankCache currentCache = currentCustomContestCache[CurrentEvent.CurrentEventId];
                    if (!currentCache.IsDirty())
                    {
                        BindDataGrid(currentCache.Cache);
                        return true;
                    }
                }
                rankSvc.GetCustomContestRanksFromEventAsync(App.CurrentUser.CustomContestId, -1);
            }
            else
            {
                // overall
                CurrentEvent.CurrentEventId = 0;

                Dictionary<int, RankCache> currentCustomContestCache;
                if (!App.RankCacheDictionary.ContainsKey(App.CurrentUser.CustomContestId))
                {
                    App.RankCacheDictionary.Add(App.CurrentUser.CustomContestId, new Dictionary<int, RankCache>());
                }
                currentCustomContestCache = App.RankCacheDictionary[App.CurrentUser.CustomContestId];

                if (currentCustomContestCache.ContainsKey(CurrentEvent.CurrentEventId))
                {
                    RankCache currentCache = currentCustomContestCache[CurrentEvent.CurrentEventId];
                    if (!currentCache.IsDirty())
                    {
                        BindDataGrid(currentCache.Cache);
                        return true;
                    }
                }
                rankSvc.GetCustomContestRanksFromEventAsync(App.CurrentUser.CustomContestId, 0);
            }

            _lastCustomContestLoaded = App.CurrentUser.CustomContestId;
            return false;
        }

        void rankSvc_GetContestRanksFromEventCompleted(object sender, GetRanksSvc.GetCustomContestRanksFromEventCompletedEventArgs arg)
        {
            //GetRanksSvc.RankObject selRank;
            
            // Vérification qu'il n'y a pas eu d'erreur
            if (arg.Error != null)
            {
                ExceptionErrorDialog dlg = new ExceptionErrorDialog("Erreur interne", arg.Error.GetType().FullName + "\n" + arg.Error.Message, ExceptionErrorDialog.ErrorType.CriticalError);
                dlg.Show();
            }
            else if (arg.myFault != null)
            {
                ExceptionErrorDialog dlg = new ExceptionErrorDialog("Erreur interne", arg.myFault.FaultType + "\n" + arg.myFault.Message, ExceptionErrorDialog.ErrorType.CriticalError);
                dlg.Show();
            }

            if (arg.Result !=null)
            {
                //selRank = BindDataGrid(e);
                BindDataGrid(arg);
                Dictionary<int, RankCache> currentCache;
                if (!App.RankCacheDictionary.ContainsKey(App.CurrentUser.CustomContestId))
                {
                    App.RankCacheDictionary.Add(App.CurrentUser.CustomContestId,new Dictionary<int,RankCache>());
                }
                currentCache = App.RankCacheDictionary[App.CurrentUser.CustomContestId];

                if (!currentCache.ContainsKey(CurrentEvent.CurrentEventId))
                {
                    currentCache.Add(CurrentEvent.CurrentEventId, new RankCache(arg));
                }
                else
                {
                    currentCache[CurrentEvent.CurrentEventId] = new RankCache(arg);
                }
            }
            BusyControl.IsBusy = false;
            rankDataGrid.Visibility = Visibility.Visible;
            rankDataGridPager.Visibility = Visibility.Visible;
        }

        private void BindDataGrid(GetRanksSvc.GetCustomContestRanksFromEventCompletedEventArgs e)
        {
            GetRanksSvc.RankObject selRank;
            Paged = new PagedCollectionView(e.Result);
            rankDataGridPager.PageSize = MaximumNumberOfUsers;
            rankDataGridPager.Source = Paged;
            rankDataGrid.ItemsSource = Paged;
            rankDataGridPager.PageIndex = GetCurrentPage(e, out selRank);
            rankDataGrid.SelectedItem = selRank;
           // return selRank;
        }

        /// <summary>
        /// List of score is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void rankSvc_GetContestRanksCompleted(object sender, GetRanksSvc.GetContestRanksCompletedEventArgs e)
        {
            GetRanksSvc.RankObject selRank;

            if (null != e.Result)
            {
                Paged = new PagedCollectionView(e.Result);
                rankDataGridPager.PageSize = MaximumNumberOfUsers;
                rankDataGridPager.Source = Paged;
                rankDataGrid.ItemsSource = Paged;
                rankDataGridPager.PageIndex = GetCurrentPage(e, out selRank);
                rankDataGrid.SelectedItem = selRank;
            }
            BusyControl.IsBusy = false;
            rankDataGrid.Visibility = Visibility.Visible;
            rankDataGridPager.Visibility = Visibility.Visible;
        }

        #region "Functions"

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        int GetCurrentPage(GetRanksSvc.GetContestRanksCompletedEventArgs evt, out GetRanksSvc.RankObject selectedRank)
        {
            int currentRank = 0;
            selectedRank = null;

            if (App.CurrentUser != null)
            {
                foreach (GetRanksSvc.RankObject rnk in evt.Result)
                {
                    if (String.Compare(rnk._userName, App.CurrentUser.UserName, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        selectedRank = rnk;
                        return (currentRank / MaximumNumberOfUsers);
                    }
                    currentRank++;
                }
            }
            return 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        int GetCurrentPage(GetRanksSvc.GetCustomContestRanksFromEventCompletedEventArgs evt, out GetRanksSvc.RankObject selectedRank)
        {
            int currentRank = 0;
            selectedRank = null;

            if (App.CurrentUser != null)
            {
                foreach (GetRanksSvc.RankObject rnk in evt.Result)
                {
                    if (String.Compare(rnk._userName, App.CurrentUser.UserName, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        selectedRank = rnk;
                        return (currentRank / MaximumNumberOfUsers);
                    }
                    currentRank++;
                }
            }
            return 0;
        }

        private FrameworkElement GetParent(FrameworkElement child, Type targetType)
        {
            object parent = child.Parent;
            if (parent != null)
            {
                if (parent.GetType() == targetType)
                {
                    return (FrameworkElement)parent;
                }
                else
                {
                    return GetParent((FrameworkElement)parent, targetType);
                }
            }
            return null;
        }

        private void rankDataGrid_LoadingRow(object sender, System.Windows.Controls.DataGridRowEventArgs e)
        {
            if (App.CurrentUser != null)
            {
                var rank = (GetRanksSvc.RankObject)e.Row.DataContext;
                if (String.Compare(rank._userName, App.CurrentUser.UserName, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    e.Row.FontWeight = FontWeights.Bold;
                }

                if ((CurrentEvent != null) && (CurrentEvent.Type == EventRankGUI.RankType.Average))
                {
                    // Affichage du score moyen et non le score total
                    DataGridColumn columnScore = this.rankDataGrid.Columns[3];
                    FrameworkElement feScore = columnScore.GetCellContent(e.Row);
                    FrameworkElement resultScore = GetParent(feScore, typeof(DataGridCell));

                    DataGridCell cellScore = (DataGridCell)resultScore;
                    TextBlock newScore = new TextBlock();
                    newScore.Text = String.Format("{0:0.00}", rank._averageScore);
                    cellScore.Content = newScore;
                    cellScore.VerticalAlignment = VerticalAlignment.Center;
                    //cellScore.Content=
                }

                DataGridColumn column = this.rankDataGrid.Columns[7];
                FrameworkElement fe = column.GetCellContent(e.Row);
                FrameworkElement result = GetParent(fe, typeof(DataGridCell));
                TextBlock currentContent = fe as TextBlock;

                if (result != null)
                {
                    if (rank._rankDifferential == 0)
                    {
                        //this.rankDataGrid.SelectedIndex = e.Row.GetIndex();                    
                        DataGridCell cell = (DataGridCell)result;
                        TextBlock newContent = new TextBlock();
                        newContent.Text = "  -";
                        cell.Content = newContent;
                        cell.VerticalAlignment = VerticalAlignment.Center;
                    }
                    else if (rank._rankDifferential < 0)
                    {
                        currentContent.Foreground = new SolidColorBrush(Colors.Red);
                    }
                    else if (rank._rankDifferential > 0)
                    {
                        TextBlock newContent = new TextBlock();
                        DataGridCell cell = (DataGridCell)result;
                        newContent.Foreground = new SolidColorBrush(Colors.Green);
                        newContent.Text = " +" + rank._rankDifferential.ToString();
                        cell.Content = newContent;
                        cell.VerticalAlignment = VerticalAlignment.Center;
                    }
                }

            }
        }

        #endregion

        #region Globalization

        public void UpdateCulture()
        {
            rankDataGrid.Columns[2].Header = LangHelper.GetString("UserName");
            rankDataGrid.Columns[3].Header = LangHelper.GetString("Score");
            rankDataGrid.Columns[4].Header = LangHelper.GetString("Played");
            rankDataGrid.Columns[5].Header = LangHelper.GetString("GP");
            rankDataGrid.Columns[6].Header = LangHelper.GetString("GS");
            rankDataGrid.Columns[7].Header = LangHelper.GetString("PR");

            RankTitle.Text = LangHelper.GetString("TabRanking");
            RankDayText.Text = LangHelper.GetString("RankDayLabel");

            // Update list of events
            int selectedEvent = RankDaysList.SelectedIndex;
            System.Collections.Generic.List<GetRanksSvc.EventObject> events = new System.Collections.Generic.List<GetRanksSvc.EventObject>();

            foreach (EventRankGUI evtRank in RankDaysList.Items)
            {
                if (evtRank.GetEvent != null)
                {
                    events.Add(evtRank.GetEvent);
                }
            }

            RankDaysList.Items.Clear();
            RankDaysList.Items.Add(new EventRankGUI(EventRankGUI.RankType.General));
            RankDaysList.Items.Add(new EventRankGUI(EventRankGUI.RankType.Average));
            foreach (GetRanksSvc.EventObject evt in events)
            {
                EventRankGUI evtGUI = new EventRankGUI(evt);
                RankDaysList.Items.Add(evtGUI);
            }
            RankDaysList.SelectedIndex = selectedEvent;
            RankTooltipText.Text = LangHelper.GetString("RankTooltipText");
        }

        #endregion

        #region "Images to see scores"

        private void DatagridImage_Loaded(object sender, RoutedEventArgs e)
        {
            StackPanel stack = sender as StackPanel;
            GetRanksSvc.RankObject currentRank = ((DataGridCell)((StackPanel)sender).Parent).DataContext as GetRanksSvc.RankObject;
            if (stack != null && currentRank != null)
            {
                BitmapImage bmi = new BitmapImage(new Uri(@"loupe.png", UriKind.Relative));
                Image image = new Image();
                image.Width = 16;
                image.Height = 16;
                image.Stretch = Stretch.Fill;
                image.Source = bmi;

                Button newButton = new Button();
                newButton.Width = 20;
                newButton.Height = 20;
                newButton.Content = image;
                newButton.Click += new RoutedEventHandler(newButton_Click);
                ToolTip tt = new ToolTip();
                tt.Content = new TextBlock()
                {
                    FontSize = 10,
                    Text = String.Format(LangHelper.GetString("ViewBets"), currentRank._userName),
                    TextWrapping = TextWrapping.Wrap
                };
                ToolTipService.SetToolTip(newButton, tt);
                stack.Children.Clear();
                stack.Children.Add(newButton);
            }

        }

        private void DatagridUserName_Loaded(object sender, RoutedEventArgs e)
        {
            StackPanel stack = sender as StackPanel;
            GetRanksSvc.RankObject currentRank = ((DataGridCell)((StackPanel)sender).Parent).DataContext as GetRanksSvc.RankObject;
            if (stack != null && currentRank != null)
            {
                TextBlock loginTextBlock = new TextBlock();
                loginTextBlock.Text = currentRank._userName;
                stack.Children.Clear();
                stack.Children.Add(loginTextBlock);
                TextBlock spaceTextBlock = new TextBlock();
                spaceTextBlock.Text = " ";
                stack.Children.Add(spaceTextBlock);
                if ((CurrentEvent != null) && (CurrentEvent.Type == EventRankGUI.RankType.General))
                {
                    int i = 0;
                    if (currentRank._bestOfEventCount.HasValue)
                    {
                        while (i < currentRank._bestOfEventCount)
                        {
                            BitmapImage bmi = new BitmapImage(new Uri(@"star.png", UriKind.Relative));
                            Image image = new Image();
                            image.Width = 16;
                            image.Height = 16;
                            image.Stretch = Stretch.Fill;
                            image.Source = bmi;
                            stack.Children.Add(image);
                            i++;
                        }
                    }
                    i = 0;
                    if (currentRank._bestOfEventInProgressCount.HasValue)
                    {
                        while (i < currentRank._bestOfEventInProgressCount)
                        {
                            BitmapImage bmi = new BitmapImage(new Uri(@"starSilver.png", UriKind.Relative));
                            Image image = new Image();
                            image.Width = 16;
                            image.Height = 16;
                            image.Stretch = Stretch.Fill;
                            image.Source = bmi;
                            stack.Children.Add(image);
                            i++;
                        }
                    }
                }

            }

        }


        void newButton_Click(object sender, RoutedEventArgs e)
        {
            Button sourceObject = sender as Button;
            StackPanel stack = sourceObject.Parent as StackPanel;
            DataGridCell cell = stack.Parent as DataGridCell;
            MainPage mp = this.Parent as MainPage;
            int eventId = 0;

            GetRanksSvc.RankObject currentRank = cell.DataContext as GetRanksSvc.RankObject;
            if (CurrentEvent.Type == EventRankGUI.RankType.SpecificDay)
            {
                eventId = CurrentEvent.GetEvent._eventId;
            }
            else
            {
                if (App.CurrentEventId == 0)
                {
                    App.CurrentEventId = EventHelper.GetCurrentEventId(App.EventsDictionary);
                }
                if (App.EventsDictionary[App.CurrentEventId]._closeDate > DateTime.UtcNow)
                {
                    if (App.CurrentEventId > 1)
                    {
                        // Pari pas encore fermé => on utilise l'identifiant du dernier
                        // événement terminé
                        int? previousEventId = EventHelper.GetLastClosedEvent(App.EventsDictionary);
                        if (previousEventId.HasValue)
                        {
                            eventId = previousEventId.Value;
                        }
                    }
                }
                else
                {
                    // Pari fermé => on utilise l'identifiant de l'événement courant
                    eventId = App.CurrentEventId;
                }
            }

            if (eventId > 0)
            {
                MatchView mv = new MatchView(currentRank, eventId);
                mv.Show();
            }
            else
            { 
                // Aucun pari n'est visible pour le moment
                MessageBox.Show(LangHelper.GetString("NoBetVisibleMessage"));
            }
            
        }

        #endregion

    }
}